home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 260_01 / rbsb.c < prev    next >
Text File  |  1988-02-23  |  16KB  |  449 lines

  1. /*
  2.  *
  3.  * -rev 01-01-87
  4.  *  This file contains Unix specific stuff for setting terminal modes,
  5.  *  very little is specific to ZMODEM or YMODEM per se (that stuff is in
  6.  *  sz.c and rz.c).  The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM
  7.  *  are also in this file, an iterative version, and a fast table driven macro
  8.  *  version, selected by #define CRCTABLE
  9.  *
  10.  *   This file is #included so the main file can set parameters such as HOWMANY.
  11.  *   See the main files (rz.c/sz.c) for compile instructions.
  12.  */
  13.  
  14. #ifdef MSDOS
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <tty.h>
  18. #define OS "MS-DOS"
  19. #endif
  20.  
  21. #ifdef V7
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <sgtty.h>
  25. #define OS "V7/BSD"
  26. #endif
  27.  
  28. #ifndef OS
  29. #ifndef USG
  30. #define USG
  31. #endif
  32. #endif
  33.  
  34. #ifdef USG
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #include <termio.h>
  38. #include <sys/ioctl.h>
  39. #define OS "SYS III/V"
  40. #endif
  41.  
  42. #if HOWMANY  > 255
  43. Howmany must be 255 or less
  44. #endif
  45.  
  46. struct
  47.    {
  48.    unsigned baudr;
  49.    int speedcode;
  50.    }
  51.    speeds[] =
  52.       {
  53.       110,    B110,
  54.       300,    B300,
  55.       600,    B600,
  56.       1200,   B1200,
  57.       2400,   B2400,
  58.       4800,   B4800,
  59.       9600,   B9600,
  60.       19200,  EXTA,
  61.       9600,   EXTB,
  62.       0,
  63.       };
  64.  
  65. int Twostop;            /* Use two stop bits */
  66.  
  67. unsigned getspeed(code)
  68. int code;
  69.    {
  70.    int n;
  71.  
  72.    for (n = 0; speeds[n].baudr; ++n)
  73. #ifndef MSDOS
  74.        if (speeds[n].speedcode == code)
  75.           return(speeds[n].baudr);
  76.    return(0);
  77. #else
  78.        if (speeds[n].baudr == code)
  79.           return(speeds[n].speedcode);
  80.    return(-1);
  81. #endif
  82.    }
  83.  
  84. #ifndef MSDOS
  85. #ifdef ICANON
  86. struct termio oldtty, tty;
  87. #else
  88. struct sgttyb oldtty, tty;
  89. struct tchars oldtch, tch;
  90. #endif
  91.  
  92. int iofd = 0;           /* File descriptor for ioctls & reads */
  93.  
  94. #else   /* MSDOS */
  95. int iofd = -1;
  96. int speed = B1200;
  97. char *port = "COM1";
  98. #endif
  99.  
  100. /*
  101. * mode(n)
  102. *  2: set a cbreak, XON/XOFF control mode if using Pro-YAM's -g option
  103. *  1: save old tty stat, set raw mode 
  104. *  0: restore original tty mode
  105. */
  106. mode(n)
  107.    {
  108.    static did0 = FALSE;
  109.  
  110.    vfile("mode:%d", n);
  111.    switch (n)
  112.       {
  113. #ifdef USG
  114.       case 2: /* Cbreak mode used by sb when -g detected */
  115.          if (!did0)
  116.             (void) ioctl(iofd, TCGETA, &oldtty);
  117.          tty = oldtty;
  118.  
  119.          tty.c_iflag = BRKINT|IXON;
  120.  
  121.          tty.c_oflag = 0;        /* Transparent output */
  122.  
  123.          tty.c_cflag &= ~PARENB; /* Disable parity */
  124.          tty.c_cflagc |= CS8;     /* Set character size = 8 */
  125.          if (Twostop)
  126.             tty.c_cflag |= CSTOPB;  /* Set two stop bits */
  127.  
  128. #ifdef XCLUDE
  129.          tty.c_lflag = XCLUDE | ISIG;
  130. #else
  131.          tty.c_lflag = ISIG;
  132. #endif
  133.  
  134.          tty.c_cc[VINTR] = Zmodem ? 03:030;      /* Interrupt char */
  135.          tty.c_cc[VMIN] = 1;
  136.  
  137.          (void) ioctl(iofd, TCSETAW, &tty);
  138.          did0 = TRUE;
  139.          return(OK);
  140.       case 1:
  141.          if (!did0)
  142.             (void) ioctl(iofd, TCGETA, &oldtty);
  143.          tty = oldtty;
  144.  
  145.          tty.c_iflag = IGNBRK;
  146.  
  147.          /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
  148.          tty.c_lflag &= ~(ECHO | ICANON | ISIG);
  149. #ifdef XCLUDE
  150.          tty.c_lflag |= XCLUDE;
  151. #endif
  152.  
  153.          tty.c_oflag = 0;        /* Transparent output */
  154.  
  155.          tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */
  156.          tty.c_cflag |= CS8;     /* Set character size = 8 */
  157.          if (Twostop)
  158.             tty.c_cflag |= CSTOPB;  /* Set two stop bits */
  159.          tty.c_cc[VMIN] = HOWMANY;  /* This many chars satisfies reads */
  160.          tty.c_cc[VTIME] = 1;       /* or in this many tenths of seconds */
  161.          (void) ioctl(iofd, TCSETAW, &tty);
  162.          did0 = TRUE;
  163.          Baudrate = getspeed(tty.c_cflag & CBAUD);
  164.          return(OK);
  165. #endif
  166. #ifdef V7
  167.       case 2: /*  This doesn't work ... */
  168.          printf("No mode(2) in V7/BSD!");
  169.          bibi(99);
  170.          if (!did0)
  171.             {
  172.             ioctl(iofd, TIOCEXCL, 0);
  173.             ioctl(iofd, TIOCGETP, &oldtty);
  174.             ioctl(iofd, TIOCGETC, &oldtch);
  175.             }
  176.          tty = oldtty;
  177.          tch = oldtch;
  178.          tch.t_intrc = Zmodem ? 03:030;  /* Interrupt char */
  179.          tty.sg_flags |= (ODDP|EVENP|CBREAK);
  180.          tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
  181.          ioctl(iofd, TIOCSETP, &tty);
  182.          ioctl(iofd, TIOCSETC, &tch);
  183.          did0 = TRUE;
  184.          return(OK);
  185.       case 1:
  186.          if (!did0)
  187.             {
  188.             ioctl(iofd, TIOCEXCL, 0);
  189.             ioctl(iofd, TIOCGETP, &oldtty);
  190.             ioctl(iofd, TIOCGETC, &oldtch);
  191.             }
  192.          tty = oldtty;
  193.          tty.sg_flags |= RAW;
  194.          tty.sg_flags &= ~ECHO;
  195.          ioctl(iofd, TIOCSETP, &tty);
  196.          did0 = TRUE;
  197.          Baudrate = getspeed(tty.sg_ospeed);
  198.          return(OK);
  199. #endif
  200. #ifdef MSDOS
  201.       case 2: /*  This doesn't work ... */
  202.          printf("No mode(2) in MSDOS");
  203.          bibi(99);
  204.       case 1:
  205.          if (!did0)
  206.             iofd = tty_open(port, speed | CS8);
  207.          did0 = TRUE;
  208.          return(OK);
  209. #endif
  210.       case 0:
  211.          if (!did0)
  212.             return(ERROR);
  213. #ifdef USG
  214.          (void) ioctl(iofd, TCSBRK, 1);          /* Wait for output to drain */
  215.          (void) ioctl(iofd, TCFLSH, 1);          /* Flush input queue */
  216.          (void) ioctl(iofd, TCSETAW, &oldtty);   /* Restore original modes */
  217.          (void) ioctl(iofd, TCXONC,1);           /* Restart output */
  218. #endif
  219. #ifdef V7
  220.          ioctl(iofd, TIOCSETP, &oldtty);
  221.          ioctl(iofd, TIOCSETC, &oldtch);
  222.          ioctl(iofd, TIOCNXCL, 0);
  223. #endif
  224. #ifdef MSDOS
  225.          tty_close(iofd);
  226. #endif
  227.          return(OK);
  228.       default:
  229.          return(ERROR);
  230.       }
  231.    }
  232.  
  233. sendbrk()
  234.    {
  235. #ifdef V7
  236. #ifdef TIOCSBRK
  237. #define CANBREAK
  238.    sleep(1);
  239.    ioctl(iofd, TIOCSBRK, 0);
  240.    sleep(1);
  241.    ioctl(iofd, TIOCCBRK, 0);
  242. #endif
  243. #endif
  244. #ifdef USG
  245. #define CANBREAK
  246.    ioctl(iofd, TCSBRK, 0);
  247. #endif
  248. #ifdef MSDOS
  249. #define CANBREAK
  250.    _combrk(iofd);
  251. #endif
  252.    }
  253.  
  254. #ifdef FIONREAD
  255. #define READCHECK
  256. /*
  257. *  Return non 0 iff something to read from io descriptor f
  258. */
  259. rdchk(f)
  260.    {
  261.    static long lf;
  262.  
  263.    ioctl(f, FIONREAD, &lf);
  264.    return ((int) lf);
  265.    }
  266. #endif
  267. #ifdef SVR2
  268. #define READCHECK
  269. #include <fcntl.h>
  270.  
  271. char checked = '\0' ;
  272. /*
  273. * Nonblocking I/O is a bit different in System V, Release 2
  274. */
  275. rdchk(f)
  276.    {
  277.    int lf, savestat = fcntl(f, F_GETFL) ;
  278.  
  279.    fcntl(f, F_SETFL, savestat | O_NDELAY) ;
  280.    lf = read(f, &checked, 1) ;
  281.    fcntl(f, F_SETFL, savestat) ;
  282.    return(lf) ;
  283.    }
  284. #endif
  285.  
  286.  
  287. #ifdef CRCTABLE
  288. /* crctab calculated by Mark G. Mendel, Network Systems Corporation */
  289. static unsigned short crctab[256] =
  290. {
  291. 0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
  292. 0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
  293. 0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
  294. 0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
  295. 0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
  296. 0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
  297. 0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
  298. 0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
  299. 0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
  300. 0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
  301. 0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
  302. 0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
  303. 0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
  304. 0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
  305. 0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
  306. 0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
  307. 0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
  308. 0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
  309. 0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c